package com.sky.d_lock_free;
/**
 * http://www.jb51.net/article/92362.htm
 * http://ifeve.com/compare-and-swap/
 * http://blog.hesey.net/2011/09/resolve-aba-by-atomicstampedreference.html
 * 
 * 上帝能够看到神像的背面
 * 
 * atomic 美[əˈtɑ:mɪk] 原子的
 * @Author:hjt
 */
public class LockFreeDemo {
	
	//AtomicInteger

	/**
	 无锁
	 
	 1.CAS算法
	 	包含3个参数CAS(V,E,N)。V表示要更新的变量，E表示预期值，N表示新值
	 	仅当V值等于E值时，才会将V的值设为N，如果V值和E值不同，则说明已经有其他线程做了更新，则当前线程什么都不做
	 	最后，CAS返回当前V的真实值
	 	
	 2.CPU指令
	 	CAS整一个操作过程是一个原子操作，它是由一条CPU指令完成的
	 	CAS的CPU指令是cmpxchg，指令代码如下：
			//accumulator = AL, AX, or EAX, depending on whether
			//a byte, word, or doubleword comparison is being performed
			if(accumulator == Destination) {
				ZF = 1;
				Destination = Source;
			} else {
				ZF = 0;
				accumulator = Destination;
			}
			目标值和寄存器里的值相等的话，就设置一个跳转标志，并且把原始数据设到目标里面去。如果不等的话，就不设置跳转标志了
	
	3.无所类的使用 - AtomicInteger
		描述：
			public final int get()						//Gets the current value.
			public final void set(int newValue)			//Sets to the given value.
			public final int getAndSet(int newValue)	//Atomically sets to the given value and returns the old value.
			public final boolean compareAndSet(int expect, int update)
			//如果当前值为预期值expect，设置为update
			public final int getAndIncrement()			//当前值加1，返回旧值
			public final int getAndDecrement()			//当前值减1，返回旧值
			public final int getAndAdd(int delta)		//当前值加delta，返回旧值
			public final int incrementAndGet()			//当前值加1，返回新值
			public final int decrementAndGet()			//当前值减1，返回新值
			public final int addAndGet(int delta)		//当前值加delta，返回新值
			
		AtomicInteger里面有很多CAS操作，典型的有:
		 	public final boolean compareAndSet(int expect, int update)
		 		{return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}
		 	对于this这个类上的偏移量为valueOffset的变量值如果与期望值expect相同，那么把这个变量的值设为update。
			其实偏移量为valueOffset的变量就是value
	 	CAS是有可能会失败的，但是失败的代价是很小的，所以一般的实现都是在一个无限循环体内，直到成功为止:
	 		public final int getAndIncrement() {
				 for (;;) {
					  int current = get();
					  int next = current + 1;
					  if (compareAndSet(current, next))
					  	return current;
				 }
			 }
			 
	4.无所类的使用 - Unsafe
	 	从类名就可知，Unsafe操作是非安全的操作:
	 		根据偏移量设置值park
	 		底层的CAS操作
	 		非公开API，在不同版本的JDK中，可能有较大差异
	 	解析：UnsafeParse
	 
	5.无所类的使用 - AtomicReference
	 	AtomicReference是一种模板类，对引用进行修改
	 	可以用来封装任意类型的数据
	 	例：AtomicReferenceDemo
	 
	6.无所类的使用 - AtomicIntegerArray
		与AtomicInteger相比，数组的实现不过是多了一个下标:
			public final boolean compareAndSet(int i, int expect, int update)
		无锁数组，封装了private final int[] array;
		运用二进制数的前导零来算数组中的偏移量：shift = 31 - Integer.numberOfLeadingZeros(scale);
			前导零的意思就是比如8位表示12,00001100，那么前导零就是1前面的0的个数，就是4
			偏移量是如何计算的？
		描述：
			public final int get(int i)		//Gets the current value at position {@code i}.
			public final int length()		//Returns the length of the array.
			public final int getAndSet(int i, int newValue)	//将数组指定下标i的值设置成新值，返回旧值
			public final boolean compareAndSet(int i, int expect, int update) 
			//进行CAS操作，如果第i个下标的值等于expect，设置为update，返回boolean
			public final int getAndIncrement(int i)	//将下标i位置的值加1，返回旧值
			public final int getAndDecrement(int i)	//将下标i位置的值减1，返回旧值
			public final int getAndAdd(int i, int delta)	//将下标i位置的值加delta，返回旧值,delta可以是负数
		
	7.无所类的使用 - AtomicReference
		作用是让普通变量也享受原子操作
		例：AtomicIntegerFieldUpdaterDemo
		说明：
			1）Updater只能修改它可见范围内的变量。因为Updater使用反射得到这个变量。如果变量不可见，就会出错。比如如果某变量申明为private，就是不可行的
			2）为了确保变量被正确的读取，它必须是volatile类型的。如果我们原有代码中未申明这个类型，那么简单得申明一下就行，这不会引起什么问题
			3）由于CAS操作会通过对象实例中的偏移量直接进行赋值，因此，它不支持static字段（Unsafe.objectFieldOffset()不支持静态变量）
		
	8.无所类的使用 - Vector 
		http://www.tuicool.com/articles/muuuAj
	 */
}
